/*.(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).*/
/* 
This File is part of HW2 in the course "Introduction To Systems Programming", 
School of Electrical Engineering, Tel-Aviv University. winter 2012.
Created by Amnon Drory.
*/
/*.(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).*/

#define _CRT_SECURE_NO_WARNINGS /* to suppress compiler warnings (VS 2010 ) */

#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <string.h>

/*.(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).*/

/**
 * STRINGS_ARE_IDENTICAL returns TRUE if both strings are identical
 */ 
#define STRINGS_ARE_IDENTICAL( str1, str2 ) ( strcmp( (str1), (str2) ) == 0 )

/*.(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).*/

/**
 * CHECK_FPRINTF_SUCCESS ends the program if fprintf() has failed.
 * Remark: This is simply a code section encapsulated in a macro to 
 * improve the readability of the main code. It is not meant to be re-usable,
 * as it relies on local variables (RetVal and OutputFile) to
 * contain specific data. 
 */ 
#define CHECK_FPRINTF_SUCCESS()								 \
	if ( ( RetVal < 0 ) && ferror( OutputFile ) )			 \
	{														 \
		fclose( OutputFile ); /* we're already handling a */ \
		/* failure, so no need to check for success here */  \
		return EXIT_CODE_FPRINTF_FAILED;					 \
	}

/*.(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).*/

enum EExitCodes {
	EXIT_CODE_SUCCESS = 1,
	EXIT_CODE_WRONG_NUM_OF_ARGUMENTS = 2,
	EXIT_CODE_ATOI_FAILED = 3,
	EXIT_CODE_FILE_OPEN_FAILED = 4,
	EXIT_CODE_FPRINTF_FAILED = 5,
	EXIT_CODE_FILE_CLOSE_FAILED = 6,
	EXIT_CODE_GENERAL_ERROR = 505
};

/*.(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).*/

enum EArgvFields
{
	INP_OUTPUT_FILENAME = 1,
	INP_SLEEP_TIME = 2,
	EXPECTED_NUM_OF_ARGUMENTS = 2
};

/*.(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).*/

const int MILLISECS_IN_SECOND = 1000;

/*.(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).(o).*/

int main( int argc, char* argv[])
{
	int SleepTimeInSeconds;
	int SleepTimeInMilliseconds;
	int RetVal;
	const int NumOfCommandLineArguments = argc - 1; /* argc also counts the exe filename */
	const char* OutputFileName = NULL;
	FILE* OutputFile = NULL;

	if ( NumOfCommandLineArguments != EXPECTED_NUM_OF_ARGUMENTS ) 
		return EXIT_CODE_WRONG_NUM_OF_ARGUMENTS;

	// --------
	// 1. Sleep
	// --------

	SleepTimeInSeconds = atoi( argv[INP_SLEEP_TIME] );

	if ( SleepTimeInSeconds == 0 )
		return EXIT_CODE_ATOI_FAILED;

	SleepTimeInMilliseconds = SleepTimeInSeconds * MILLISECS_IN_SECOND;

	Sleep( SleepTimeInMilliseconds );

	// -----------------------
	// 2. Print to output file
	// -----------------------

	OutputFileName = argv[INP_OUTPUT_FILENAME];
	
	OutputFile = fopen( OutputFileName , "w" );
	if ( OutputFile == NULL ) return EXIT_CODE_FILE_OPEN_FAILED;

	RetVal = fprintf( OutputFile, "%d\n", SleepTimeInSeconds );	
	CHECK_FPRINTF_SUCCESS();

	RetVal = fclose( OutputFile );
	if ( RetVal == EOF ) return EXIT_CODE_FILE_CLOSE_FAILED;

	// ---------------------
	// 3. Exit Successfully:
	// ---------------------
	return EXIT_CODE_SUCCESS;
}